package com.dragee.modules.work.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragee.common.PageUtils;
import com.dragee.common.R;
import com.dragee.config.exception.BusinessException;
import com.dragee.constants.CommonConstants;
import com.dragee.modules.sys.entity.UserEntity;
import com.dragee.modules.sys.service.UserService;
import com.dragee.modules.work.dao.CompetitionDao;
import com.dragee.modules.work.dto.ImportOrderSortExport;
import com.dragee.modules.work.entity.*;
import com.dragee.modules.work.service.*;
import com.dragee.utils.IdUtils;
import com.dragee.utils.LoginUserUtil;
import com.dragee.utils.StringUtils;
import com.dragee.utils.WrapperUtil;
import com.dragee.utils.excel.CommonListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("competitionService")
public class CompetitionServiceImpl extends ServiceImpl<CompetitionDao, CompetitionEntity> implements CompetitionService {


    @Resource
    private CompetitionDao competitionDao;
    @Autowired
    private UserService userService;
    @Autowired
    private CompetitionProjectService competitionProjectService;
    @Autowired
    private CompetitionService competitionService;
    @Autowired
    private ApplyService applyService;
    @Autowired
    private ApplyProjectService applyProjectService;
    @Autowired
    private TeamService teamService;
    @Autowired
    private TeamAthleteService teamAthleteService;
    @Autowired
    private CompetitionOrderService competitionOrderService;

    private String business = "competition";


    /**
     * 导出的时候临时存储的orderID 此处线程不安全 注意并发
     */
    private static String importOrderId;

    /**
    * 列表
    */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        int limit = params.get(CommonConstants.LIMIT) == null
                ?CommonConstants.LIMIT_SIZE:Integer.parseInt(params.get(CommonConstants.LIMIT).toString());
        int start = params.get(CommonConstants.START) == null
                ?CommonConstants.START_SIZE:Integer.parseInt(params.get(CommonConstants.START).toString());
        QueryWrapper<CompetitionEntity> wrapper =
                WrapperUtil.getWrapper(business, params, CompetitionEntity.class);
        setWrapper(wrapper);
        IPage<CompetitionEntity> page = new Page<>(start, limit);
        page = baseMapper.selectPage(page, wrapper.select());
        return new PageUtils(page);
    }

    private QueryWrapper<CompetitionEntity> setWrapper
            (QueryWrapper<CompetitionEntity> wrapper ) {
        UserEntity user = userService.getById(LoginUserUtil.getLoginUserId());
        if (StrUtil.isNotBlank(user.getProvince())) {
            wrapper.eq("province", user.getProvince());
        }
        return wrapper;
    }


    @Override
    public CompetitionEntity getInfoById(String competitionId) {
        CompetitionEntity competitionEntity = getById(competitionId);
        List<CompetitionProjectEntity> projects = competitionProjectService.getProjectByCompetition(competitionId);
        competitionEntity.setProjects(projects);
        return competitionEntity;
    }

    @Override
    @Transactional
    public R importData(MultipartFile file, String orderId) throws IOException {
        importOrderId = orderId;
        //填充对应词典 sex: (1:男, 2:女)
        Map<String, Map<String,Object>> map = new HashMap<>();
        //解析器
        CommonListener<ImportOrderSortExport> commonListener
                = new CommonListener<>(map, ImportOrderSortExport.class,this::excelBatch);
        EasyExcel.read(file.getInputStream())
                .head(ImportOrderSortExport.class)
                .registerReadListener(commonListener)
                .sheet()
                .doRead();
        List<String> msgList = commonListener.getMsgList();
        if(msgList.size()>0){
            return R.error(StringUtils.join(msgList,","));
        }
        return R.ok();
    }

    /** 导入执行入库方法
     * @param datas
     * @return
     */
    private boolean excelBatch (List<ImportOrderSortExport> datas) {
        // 比赛校验
        List<String> competionNames = datas.stream()
                .map(ImportOrderSortExport::getCompetitionName).distinct().collect(Collectors.toList());
        if (competionNames.size() != 1) {
            throw new BusinessException("只允许导入一场比赛的数据");
        }
        String competionName = competionNames.get(0);
        CompetitionEntity competition = competitionService.getOne(new QueryWrapper<CompetitionEntity>().eq("name", competionName), false);
        if (competition == null) {
            throw new BusinessException("比赛名称不存在, 请先创建比赛");
        }
        // 校验组别
        List<String> groups = datas.stream()
                .map(ImportOrderSortExport::getGroups).distinct().collect(Collectors.toList());
        for (String group : groups) {
            if (competition.getGroups().indexOf(group) == -1) {
                throw new BusinessException(group + "组别不存在");
            }
        }

        List<CompetitionProjectEntity> projects = competitionProjectService.getProjectByCompetition(competition.getId()+"");
        // 检验大类
        String projectTypeStr = projects.stream().map(CompetitionProjectEntity::getType).distinct().collect(Collectors.joining(","));
        List<String> projectTypes = datas.stream()
                .map(ImportOrderSortExport::getProjectType).distinct().collect(Collectors.toList());
        for (String projectType : projectTypes) {
            if (projectTypeStr.indexOf(projectType) == -1) {
                throw new BusinessException(projectType + "大类不存在");
            }
        }
        // 检验项目
        String projectNameStr = projects.stream().map(CompetitionProjectEntity::getName).collect(Collectors.joining(","));
        List<String> projectNames = datas.stream()
                .map(ImportOrderSortExport::getProjectName).collect(Collectors.toList());
        for (String projectName : projectNames) {
            if (projectNameStr.indexOf(projectName) == -1) {
                throw new BusinessException(projectName + "项目不存在");
            }
        }
        // 检查该场次是否已经导入
        int count = applyProjectService.count(new QueryWrapper<ApplyProjectEntity>().eq("orderId", importOrderId));
        if (count > 0) {
            throw new BusinessException("当前场次已经导入过数据，不能重复导入");
        }

        // 删除掉之前的数据
        CompetitionOrderEntity order = competitionOrderService.getById(importOrderId);

        List<String> applyProjectIds = new ArrayList<>();
        for (ImportOrderSortExport data : datas) {
            // saveOrUpdate(data);
            // 设置队伍
            TeamEntity team = teamService.getTeamByName(data.getTeamName());
            if (team == null) {
                team = new TeamEntity();
                team.setName(data.getTeamName());
                team.setProvince(data.getProvince());
                team.setCode(IdUtils.getId10());
                team.setIsImport(1);
                teamService.saveOrUpdate(team);
            }
            // 设置运动员
            String[] athleteNameArr = data.getAthleteNames().split(",");
            for (String name : athleteNameArr) {
                TeamAthleteEntity athlete = teamAthleteService.getOne(new QueryWrapper<TeamAthleteEntity>()
                        .eq("teamKey", team.getId()).eq("name", name), false);
                if (athlete == null) {
                    TeamAthleteEntity a = new TeamAthleteEntity();
                    a.setName(name);
                    a.setTeamId(team.getCode());
                    a.setTeamKey(team.getId() + "");
                    a.setApplyStatus("已加入");
                    a.setIsImport(1);
                    teamAthleteService.saveOrUpdate(a);
                }

            }
            // 设置报名表
            ApplyEntity apply = new ApplyEntity();
            apply.setTeamId(team.getId() + "");
            apply.setTitle(team.getName() + "-" + competition.getName());
            apply.setCompetitionId(competition.getId() + "");
            apply.setCompetitionName(competition.getName());
            apply.setProvince(data.getProvince());
            apply.setStatus("已通过");
            apply.setIsImport(1);
            applyService.saveOrUpdate(apply);

            ApplyProjectEntity applyProject = new ApplyProjectEntity();
            applyProject.setApplyId(apply.getId() + "");
            applyProject.setCompetitionId(competition.getId() + "");
            applyProject.setOrderId(importOrderId);
            applyProject.setType(data.getProjectType());
            applyProject.setGroups(data.getGroups());
            CompetitionProjectEntity project = competitionProjectService.getOne(new QueryWrapper<CompetitionProjectEntity>()
                    .eq("competitionId", competition.getId())
                    .eq("name", data.getProjectName())
                    .eq("type", data.getProjectType()), false);
            if (project == null) {
                throw new BusinessException("大类：" + data.getProjectType() + " 项目：" + data.getProjectName() + " 不存在");
            }
            applyProject.setProjectId(project.getId() + "");
            String athleteIdsByNames = teamAthleteService.getAthleteIdsByNames(team.getId() + "", data.getAthleteNames());
            applyProject.setAthleteIds(athleteIdsByNames);
            applyProject.setStatus("未打分");
            applyProject.setIsImport(1);
            applyProjectService.saveOrUpdate(applyProject);
            applyProjectIds.add(applyProject.getId() + "");
        }
        order.setApplyProjectIds(ArrayUtil.join(applyProjectIds.toArray(), ","));
        competitionOrderService.saveOrUpdate(order);
        return true;
    }


    public static void main(String[] args) {
         String str = "青年组";
        String a = "青年组,小学乙组7-9岁,小学甲组10-12岁,小学混合组,初中组,高中组,职高组,高职高专组,大学普通院校组,大学体育院校组,幼儿组,儿童组,少年组,老年组,中年组";

        System.out.println(a.indexOf(str));

    }

}

